﻿using SiMay.Sockets.Delegate;
using SiMay.Sockets.Tcp.Pooling;
using SiMay.Sockets.Tcp.TcpConfiguration;
using System;
using System.Collections.Concurrent;
using System.Net.Sockets;

namespace SiMay.Sockets.Tcp.Session
{
    /// <summary>
    /// Session基础类
    /// </summary>
    public abstract class TcpSocketSaeaSession
    {
        protected NotifyEventHandler<TcpSocketCompletionNotify, TcpSocketSaeaSession> NotifyEventHandler { get; set; }

        /// <summary>
        /// 配置信息
        /// </summary>
        protected TcpSocketConfigurationBase Configuration { get; set; }

        /// <summary>
        /// 异步操作对象池
        /// </summary>
        protected SaeaAwaiterPool HandlerSaeaPool { get; set; }

        /// <summary>
        /// 所在Session池
        /// </summary>
        protected SessionPool SessionPools { get; set; }

        /// <summary>
        /// Session所属主连接组件
        /// </summary>
        public TcpSocketSaeaEngineBased Agent { get; set; }

        /// <summary>
        /// 根据接收数据得到的总数据长度,重新定义的数据缓存
        /// </summary>
        public byte[] CompletedBuffer { get; protected set; }

        /// <summary>
        /// 发送数据缓存区大小
        /// </summary>
        public int SendTransferredBytes { get; protected set; }

        /// <summary>
        /// 接收数据缓存区大小
        /// </summary>
        public int ReceiveBytesTransferred { get; protected set; }

        public ConcurrentDictionary<string, object> AppTokens { get; set; }

        /// <summary>
        /// 连接的Socket对象
        /// </summary>
        public Socket Socket { get; protected set; }

        /// <summary>
        /// 返回是否Socket连接
        /// </summary>
        public bool Connected => Socket != null && Socket.Connected;

        /// <summary>
        /// 连接状态
        /// </summary>
        public TcpSocketConnectionState State { get; protected set; }

        /// <summary>
        /// 连接成功的时间
        /// </summary>
        public DateTime StartTime { get; protected set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="notifyEventHandler"></param>
        /// <param name="configuration"></param>
        /// <param name="handlerSaeaPool"></param>
        /// <param name="sessionPool"></param>
        /// <param name="agent"></param>
        internal TcpSocketSaeaSession(
            NotifyEventHandler<TcpSocketCompletionNotify, TcpSocketSaeaSession> notifyEventHandler,
            TcpSocketConfigurationBase configuration,
            SaeaAwaiterPool handlerSaeaPool,
            SessionPool sessionPool,
            TcpSocketSaeaEngineBased agent)
        {
            NotifyEventHandler = notifyEventHandler;
            Configuration = configuration;
            HandlerSaeaPool = handlerSaeaPool;
            SessionPools = sessionPool;
            Agent = agent;
        }

        /// <summary>
        /// Session与Socket关联并初始化
        /// </summary>
        /// <param name="socket">连接的Socket</param>
        internal abstract void Attach(Socket socket);

        /// <summary>
        /// Session清空信息
        /// </summary>
        internal abstract void Detach();

        internal abstract void StartProcess();

        public abstract void SendAsync(byte[] data);

        public abstract void SendAsync(byte[] data, int offset, int lenght);

        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="notify">是否触发连接断开事件</param>
        public abstract void Close(bool notify);
    }
}
